/**
 * Notes: 基础业务逻辑
 * Ver : CCMiniCloud Framework 2.0.9 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2022-04-24 04:00:00 
 */

const AppError = require('../../core/app_error.js');
const appCode = require('../../core/app_code.js');
const timeUtil = require('../../helpers/time_util.js');
const { SetupModel, CacheModel, ConfigModel } = require('../config/models_config');
const util = require('../../helpers/util.js');

class BaseService {
	constructor() {
		// 当前时间戳
		this._timestamp = timeUtil.time();

	}

	/**
	 * 抛出异常
	 * @param {*} msg 
	 * @param {*} code 
	 */
	AppError(msg, code = appCode.LOGIC) {
		throw new AppError(msg, code);
	}

	/** 时期范围处理 */
	fmtSearchDate(where, search, field) {
		if (!search || search.length != 21 || !search.includes('#')) return where;

		let arr = search.split('#');
		let start = arr[0];
		let end = arr[1];
		where[field] = ['between', start, end];
		return where;
	}

	/* 数据库字段排序处理 */
	fmtOrderBySort(sortVal, defaultSort) {
		let orderBy = {
			[defaultSort]: 'desc'
		};

		if (sortVal.includes('|')) {
			let field = sortVal.split('|')[0];
			let order = sortVal.split('|')[1];
			orderBy = {
				[field]: order,
			};
			if (defaultSort != field) orderBy[defaultSort] = 'desc';
		}
		return orderBy;
	}

	/** 系统初始化完毕 */
	async initSetup() {

	}

	/**
	 * 获取缓存数据
	 * @param {string} key 缓存键名
	 * @returns {Promise<any>} 缓存数据
	 */
	async getCache(key) {
		if (!key) return null;
		
		// 避免缓存键名太长
		if (key.length > 100) {
			key = 'hash_' + util.md5(key);
		}
		
		try {
			// 生成完整的缓存键名
			const fullKey = `${this.getProjectId()}_${key}`;
			const cacheData = await CacheModel.getOne({
				CACHE_KEY: fullKey,
				CACHE_EXPIRE_TIME: ['>', timeUtil.time()]
			});
			
			if (!cacheData) return null;
			
			// 解析数据
			try {
				return JSON.parse(cacheData.CACHE_VALUE);
			} catch (err) {
				return cacheData.CACHE_VALUE;
			}
		} catch (err) {
			console.error('读取缓存失败:', err);
			return null;
		}
	}
	
	/**
	 * 设置缓存数据
	 * @param {string} key 缓存键名
	 * @param {any} value 缓存值
	 * @param {number} expire 过期时间(秒)
	 * @returns {Promise<boolean>} 是否成功
	 */
	async setCache(key, value, expire = 300) {
		if (!key) return false;
		
		// 避免缓存键名太长
		if (key.length > 100) {
			key = 'hash_' + util.md5(key);
		}
		
		try {
			// 生成完整的缓存键名
			const fullKey = `${this.getProjectId()}_${key}`;
			
			// 序列化数据
			let cacheValue = '';
			if (typeof value === 'object') {
				cacheValue = JSON.stringify(value);
			} else {
				cacheValue = value?.toString() || '';
			}
			
			// 计算过期时间
			const now = timeUtil.time();
			const expireTime = now + expire;
			
			// 先查询是否存在
			const cacheData = await CacheModel.getOne({
				CACHE_KEY: fullKey
			});
			
			if (cacheData) {
				// 更新缓存
				await CacheModel.edit({
					CACHE_KEY: fullKey
				}, {
					CACHE_VALUE: cacheValue,
					CACHE_EXPIRE_TIME: expireTime,
					CACHE_EDIT_TIME: now
				});
			} else {
				// 新增缓存
				await CacheModel.insert({
					CACHE_KEY: fullKey,
					CACHE_VALUE: cacheValue,
					CACHE_EXPIRE_TIME: expireTime,
					CACHE_ADD_TIME: now,
					CACHE_EDIT_TIME: now
				});
			}
			
			return true;
		} catch (err) {
			console.error('设置缓存失败:', err);
			return false;
		}
	}
	
	/**
	 * 删除缓存数据
	 * @param {string} key 缓存键名
	 * @returns {Promise<boolean>} 是否成功
	 */
	async delCache(key) {
		if (!key) return false;
		
		// 避免缓存键名太长
		if (key.length > 100) {
			key = 'hash_' + util.md5(key);
		}
		
		try {
			// 生成完整的缓存键名
			const fullKey = `${this.getProjectId()}_${key}`;
			
			// 删除缓存
			await CacheModel.del({
				CACHE_KEY: fullKey
			});
			
			return true;
		} catch (err) {
			console.error('删除缓存失败:', err);
			return false;
		}
	}
	
	/**
	 * 清理过期缓存
	 * @returns {Promise<boolean>} 是否成功
	 */
	async cleanCache() {
		try {
			// 删除所有过期缓存
			await CacheModel.del({
				CACHE_EXPIRE_TIME: ['<', timeUtil.time()]
			}, true);
			
			return true;
		} catch (err) {
			console.error('清理缓存失败:', err);
			return false;
		}
	}

}

module.exports = BaseService;